package com.distribution.system.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.distribution.common.core.domain.entity.SysUser;
import com.distribution.common.exception.ServiceException;
import com.distribution.common.utils.DictUtils;
import com.distribution.common.utils.StringUtils;
import com.distribution.system.domain.dto.CmccDaAccountDetailAddDto;
import com.distribution.system.domain.dto.CmccDaAccountDetailQueryDto;
import com.distribution.system.domain.entity.CmccDaAccountDetail;
import com.distribution.system.domain.entity.CmccDaOrder;
import com.distribution.system.domain.entity.CmccDaProxyProductManage;
import com.distribution.system.enums.OrderStatusEnum;
import com.distribution.system.mapper.CmccDaAccountDetailMapper;
import com.distribution.system.mapper.SysUserMapper;
import com.distribution.system.service.CmccDaAccountDetailService;
import com.distribution.system.service.CmccDaProxyProductManageService;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * (CmccDaAccountDetail)表服务实现类
 */
@Slf4j
@Service("cmccDaAccountDetailService")
public class CmccDaAccountDetailServiceImpl extends ServiceImpl<CmccDaAccountDetailMapper, CmccDaAccountDetail> implements CmccDaAccountDetailService {
    private static final Logger accountDetailLog = LoggerFactory.getLogger("accountDetailLog");

    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    CmccDaProxyProductManageService cmccDaProxyProductManageService;

    @Override
    public List<CmccDaAccountDetail> selectCmccDaAccountDetail(CmccDaAccountDetailQueryDto cmccDaAccountDetailQueryDto) {
        LambdaQueryWrapper<CmccDaAccountDetail> cmccDaAccountDetailQueryWrapper = new LambdaQueryWrapper<>();
        SysUser currentSysUser = cmccDaAccountDetailQueryDto.getCurrentSysUser();
        if (currentSysUser.isOperationSupervisor()){
            cmccDaAccountDetailQueryWrapper.in(CmccDaAccountDetail::getUserId, cmccDaAccountDetailQueryDto.getUserIdList());
            if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getUserName())) {
                cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getUserName, cmccDaAccountDetailQueryDto.getUserName());
            }
            if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getAccount())) {
                cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getAccount, cmccDaAccountDetailQueryDto.getAccount());
            }
        }else {
            cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getUserId, currentSysUser.getUserId());
        }
        // 模糊查询
        if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getSearchValue())) {
            cmccDaAccountDetailQueryWrapper.like(CmccDaAccountDetail::getOrderId, cmccDaAccountDetailQueryDto.getSearchValue())
                    .or().like(CmccDaAccountDetail::getChoosePhone, cmccDaAccountDetailQueryDto.getSearchValue());
        }
        if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getDetailType())) {
            cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getDetailType, cmccDaAccountDetailQueryDto.getDetailType());
        }
        if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getOrderId())) {
            cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getOrderId, cmccDaAccountDetailQueryDto.getOrderId());
        }
        if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getChoosePhone())) {
            cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getChoosePhone,cmccDaAccountDetailQueryDto.getChoosePhone());
        }
        if (StringUtils.isNotBlank(cmccDaAccountDetailQueryDto.getProductName())) {
            cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getProductName,cmccDaAccountDetailQueryDto.getProductName());
        }
        if (cmccDaAccountDetailQueryDto.getEndTime() != null) {
            cmccDaAccountDetailQueryWrapper.le(CmccDaAccountDetail::getUpdateTime,cmccDaAccountDetailQueryDto.getEndTime());
        }
        if (cmccDaAccountDetailQueryDto.getBeginTime() != null) {
            cmccDaAccountDetailQueryWrapper.ge(CmccDaAccountDetail::getUpdateTime,cmccDaAccountDetailQueryDto.getBeginTime());
        }
        cmccDaAccountDetailQueryWrapper.eq(CmccDaAccountDetail::getOrderStatus,1);
        cmccDaAccountDetailQueryWrapper.orderByDesc(CmccDaAccountDetail::getUpdateTime);
        return list(cmccDaAccountDetailQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCmccDaAccountDetailPhone(String orderNo, String choosePhone) {
        log.info("更新指定订单号{}资金明细的选购号码为{}", orderNo, choosePhone);
        accountDetailLog.info("更新指定订单号{}资金明细的选购号码为{}", orderNo, choosePhone);
        List<CmccDaAccountDetail> list = lambdaQuery().eq(CmccDaAccountDetail::getOrderId, orderNo).list();
        if (list.isEmpty()) {
            return;
        }
        list.forEach(f -> {
            if (StringUtils.isNotEmpty(choosePhone) && !choosePhone.equals(f.getChoosePhone())) {
                f.setChoosePhone(choosePhone);
                f.setUpdateTime(LocalDateTime.now());
                updateById(f);
            }
        });
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    @Synchronized
    public void updateCmccDaAccountDetail(String orderNo, String choosePhone) {
        log.info("更新指定订单号{}的资金明细...", orderNo);
        accountDetailLog.info("更新指定订单号{}的资金明细...", orderNo);
        QueryWrapper<CmccDaAccountDetail> cmccDaAccountDetailQueryWrapper = new QueryWrapper<>();
        cmccDaAccountDetailQueryWrapper.eq("order_id",orderNo);
        cmccDaAccountDetailQueryWrapper.eq("order_status",0);
        List<CmccDaAccountDetail> list = list(cmccDaAccountDetailQueryWrapper);
        if (list.isEmpty()) {
            return;
        }
        list.forEach(a -> {
            if (StringUtils.isNotEmpty(choosePhone) &&  !choosePhone.equals(a.getChoosePhone())) {
                a.setChoosePhone(choosePhone);
            }
            Integer userId = a.getUserId();
            SysUser sysUser = sysUserMapper.selectUserById(userId.longValue());
            if (sysUser != null) {
                BigDecimal commission = sysUser.getCommission();
                a.setFrontAmount(commission);
                a.setAfterAmount(commission.add(a.getChangeAmount()));
                a.setUpdateTime(LocalDateTime.now());
                a.setOrderStatus(1);
                sysUser.setCommission(commission.add(a.getChangeAmount()));
                sysUser.setUpdateTime(new Date());
                sysUserMapper.updateUser(sysUser);
                log.info("更新资金明细后ID为{}的用户当前佣金总和为{}", userId, sysUser.getCommission());
                accountDetailLog.info("更新资金明细后ID为{}的用户当前佣金总和为{}", userId, sysUser.getCommission());
            }
        });
        if (!list.isEmpty()) {
            updateBatchById(list);
        }
    }

    @Transactional
    @Override
    public void addAccountDetail(@Validated CmccDaAccountDetailAddDto cmccDaAccountDetailAddDto){
        log.info("添加资金明细 => {}", cmccDaAccountDetailAddDto);
        accountDetailLog.info("添加资金明细 => {}", cmccDaAccountDetailAddDto);
        String detailType = cmccDaAccountDetailAddDto.getDetailType();// 明细类型
        BigDecimal changeAmount = cmccDaAccountDetailAddDto.getChangeAmount();// 改动金额
        if ("0".equals(detailType) || "1".equals(detailType)) throw new ServiceException("暂不支持订单奖励和下级抽成");// 订单奖励和下级抽成走addAccountDetailByOrder方法
        CmccDaAccountDetail cmccDaAccountDetail = new CmccDaAccountDetail();
        // 设置备注
        if ("2".equals(detailType)){// 佣金提现
            cmccDaAccountDetail.setWithdrawId(cmccDaAccountDetailAddDto.getWithdrawId());// 设置资金提现记录ID
            cmccDaAccountDetail.setRemark(DateUtil.now() + "提现佣金" + changeAmount + "元");
        }
        if ("3".equals(detailType)){
            if (StringUtils.isBlank(cmccDaAccountDetailAddDto.getRemark())) {
                cmccDaAccountDetail.setRemark(DateUtil.now() + "线下转账" + changeAmount + "元");
            }else {
                cmccDaAccountDetail.setRemark(cmccDaAccountDetailAddDto.getRemark());
            }
        }
        // 设置用户ID和代理名称
        SysUser sysUser = cmccDaAccountDetailAddDto.getSysUser();// 明细用户
        cmccDaAccountDetail.setUserId(sysUser.getUserId().intValue());
        cmccDaAccountDetail.setUserName(sysUser.getNickName());
        // 设置变动金额
        BigDecimal currentCommission = sysUser.getCommission();
        BigDecimal frontAmount = cmccDaAccountDetailAddDto.getFrontAmount();
        BigDecimal afterAmount = cmccDaAccountDetailAddDto.getAfterAmount();
        if (currentCommission.compareTo(afterAmount) != 0) throw new ServiceException("代理佣金有所变动，请重试");
        cmccDaAccountDetail.setFrontAmount(frontAmount);
        cmccDaAccountDetail.setChangeAmount(changeAmount);
        cmccDaAccountDetail.setAfterAmount(afterAmount);
        if (frontAmount.compareTo(afterAmount) < 0) throw new ServiceException("佣金增加请联系技术支持！");
        // 设置明细类型和明细名称
        cmccDaAccountDetail.setDetailType(detailType);
        cmccDaAccountDetail.setDetailName(DictUtils.getDictLabel("detail_type", detailType));
        // 设置创建更新时间
        cmccDaAccountDetail.setCreateTime(LocalDateTime.now());
        cmccDaAccountDetail.setUpdateTime(LocalDateTime.now());
        // 设置状态为成功
        cmccDaAccountDetail.setOrderStatus(1);
        save(cmccDaAccountDetail);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    @Override
    public List<CmccDaAccountDetail> addAccountDetailByOrder(CmccDaOrder cmccDaOrder) {
        log.info("下单成功添加资金明细时传递的订单信息 => {}", cmccDaOrder);
        accountDetailLog.info("下单成功添加资金明细时传递的订单信息 => {}", cmccDaOrder);
        List<CmccDaAccountDetail> cmccDaAccountDetails = new ArrayList<>();
        if (StringUtils.isEmpty(cmccDaOrder.getOrderId())) {
            return cmccDaAccountDetails;
        }
        try {
            if (OrderStatusEnum.UN_ORDER_SUCCESS.getOrderStatus().equals(cmccDaOrder.getOrderStatus())
                    || OrderStatusEnum.UN_ORDER_SUCCESS.getOrderStatusDesc().equals(cmccDaOrder.getOrderStatusDesc())
                    || "下单成功".equals(cmccDaOrder.getChannelOrderStatusMsg())) {
                //保证当前账单详情绑定用户存在
                Long userId = cmccDaOrder.getUserId();
                SysUser sysUser = sysUserMapper.selectUserById(userId);
                if (sysUser == null) {
                    return cmccDaAccountDetails;
                }
                //代理&号卡关联表中查找与客户订单信息相符的记录
                CmccDaProxyProductManage cmccDaProxyProductManage = cmccDaProxyProductManageService.getOne(new LambdaQueryWrapper<CmccDaProxyProductManage>()
                        .eq(CmccDaProxyProductManage::getUserId, userId)
                        .eq(CmccDaProxyProductManage::getProductCode, cmccDaOrder.getProductCode()), false);
                if (cmccDaProxyProductManage != null) {
                    //计算佣金
                    calculateCommission(sysUser, cmccDaProxyProductManage,null,null, cmccDaOrder, cmccDaAccountDetails);
                }
            }
        } catch (Exception e) {
            log.error("添加资金明细时发生异常{}", e.getMessage());
            accountDetailLog.error("添加资金明细时发生异常{}", e.getMessage());
            throw e;
        }
        return cmccDaAccountDetails;
    }

    /**
    * @Author: GodLu
    * @Date: 2024/5/9 9:37
    * @Description: 计算佣金
    * @param sysUser 下单用户
    * @param cmccDaProxyProductManage 代理卡管理信息
    * @param sysUserDown 下级代理
    * @param cmccDaProxyProductManageDown 下级代理卡管理信息
    * @param cmccDaOrder 订单信息
    * @param cmccDaAccountDetails 资金明细
    * @return: void
    */
    public void  calculateCommission(SysUser sysUser, CmccDaProxyProductManage cmccDaProxyProductManage,
                                     SysUser sysUserDown, CmccDaProxyProductManage cmccDaProxyProductManageDown,
                                     CmccDaOrder cmccDaOrder, List<CmccDaAccountDetail> cmccDaAccountDetails) {
        CmccDaAccountDetail cmccDaAccountDetail = new CmccDaAccountDetail();
        cmccDaAccountDetail.setOrderId(cmccDaOrder.getOrderId());
        cmccDaAccountDetail.setProductName(cmccDaOrder.getProductName());
        cmccDaAccountDetail.setProductParam(cmccDaOrder.getProductParam());
        cmccDaAccountDetail.setUserId(sysUser.getUserId().intValue());
        cmccDaAccountDetail.setUserName(sysUser.getNickName());
        cmccDaAccountDetail.setChoosePhone(cmccDaOrder.getChoosePhone());
        cmccDaAccountDetail.setOrderStatus(0);
        cmccDaAccountDetail.setCreateTime(LocalDateTime.now());
        cmccDaAccountDetail.setUpdateTime(LocalDateTime.now());
        cmccDaAccountDetail.setRemark("");
        cmccDaAccountDetail.setDetailType("0");
        cmccDaAccountDetail.setDetailName(DictUtils.getDictLabel("detail_type", "0"));
        // 获取自己的佣金
        BigDecimal myCommision = cmccDaProxyProductManage.getCommission() == null ? new BigDecimal(0) : cmccDaProxyProductManage.getCommission();
        // 如果存在下级代理，则佣金为下级抽成
        if (sysUserDown != null && cmccDaProxyProductManageDown != null) {
            // 获取下级佣金
            BigDecimal bigDecimal1 = cmccDaProxyProductManageDown.getCommission() == null ? new BigDecimal(0) : cmccDaProxyProductManageDown.getCommission();
            //自己佣金 - 下级佣金 = 抽成
            myCommision = myCommision.subtract(bigDecimal1);
            cmccDaAccountDetail.setDetailType("1");
            cmccDaAccountDetail.setDetailName(DictUtils.getDictLabel("detail_type", "1"));
        }
        // 佣金 <= 0 则退出
        if (myCommision.compareTo(new BigDecimal(0)) <= 0 ) {
            return;
        }
        cmccDaAccountDetail.setChangeAmount(myCommision);
        //保存账户信息
        save(cmccDaAccountDetail);
        cmccDaAccountDetails.add(cmccDaAccountDetail);
        // 获取上级信息
        SysUser sysUserUp = sysUserMapper.selectUserById(sysUser.getParentId());
        if (sysUserUp == null) return;
        CmccDaProxyProductManage cmccDaProxyProductManageUp = cmccDaProxyProductManageService.lambdaQuery()
                .eq(CmccDaProxyProductManage::getUserId, sysUserUp.getUserId())
                .eq(CmccDaProxyProductManage::getProductCode, cmccDaOrder.getProductCode())
                .one();
        if (cmccDaProxyProductManageUp == null) return;
        calculateCommission(sysUserUp, cmccDaProxyProductManageUp,sysUser, cmccDaProxyProductManage,cmccDaOrder,cmccDaAccountDetails);
    }
}
